home *** CD-ROM | disk | FTP | other *** search
- Path: druid.borland.com!usenet
- From: pete@borland.com (Pete Becker)
- Newsgroups: comp.lang.c
- Subject: Re: A little shift to the left and a little shift to the right.
- Date: 17 Apr 1996 18:26:43 GMT
- Organization: Borland International
- Message-ID: <4l3d53$dom@druid.borland.com>
- References: <4knegm$40d@crl.crl.com>
- NNTP-Posting-Host: pbecker.borland.com
- Mime-Version: 1.0
- Content-Type: Text/Plain; charset=ISO-8859-1
- X-Newsreader: WinVN 0.99.5
-
- In article <4knegm$40d@crl.crl.com>, smuegge@crl.com says...
- >
- >Our trusty PL/M-to-C translator generated the C operators << and >>
- >whenever it encountered the PL/M operators SHL and SHR.
- >
- >In one case the original coder had used these bit shifting operators
- >to clear out the top nibble of a byte using the following code.
- >(Actually this is the C code the translator generated less the
- >proprietary variable names. :))
- >
- > x = ( ( y << 4 ) >> 4 );
- >
- > (The name of the coder will remain a secret, and yes I know a
- > simple "& 0x0f" would be a more obvious solution. but the same
- > problem is exhibited for any left-shift followed by a right-shift)
- >
- >Both the variables x and y are bytes ( unsigned chars ).
- >
- >The results of this code is the the value of y is assigned to
- >x without any modification. The same results as simple assignment
- >(x = y). It turns out that every C compiler I've tried ( Intel-C,
- >Microsoft VC++, and gcc) exhibits this same behaviour.
- >Looking at the assembly code generated by all three compilers the
- >reason the shifts have no effect is because they do them with 32
- >bit registers. So, when the bits are shifted to the left by 4 they
- >aren't "lost" as one might expect. Then the right shift just
- >returns all the bits to original position.
- >
- >By using a typecast two of the compilers (Intel-C and gcc) will
- >do what the original coder intended, mask off the the top nibble of
- >a byte. Microsoft's compiler just ignored the typecast and
- >generated the same code as it did without the typecast.
- >
- > x = ( ( unsigned char ) ( y << 4 ) >> 4 );
- >
- >Also, seperating the two shifts into two statements all the compilers
- >work as originally hoped.
- >
- > x = y << 4;
- > x = x >> 4;
- >
- >Anyway, any experts in C want to tell me whether these compilers
- >are just doing these operations correctly or incorrectly? Also,
- >what about the fact that the Microsoft compiler ignores the typecast
- >unlike Intel-C and gcc? Also, if any experts in human behaviour
- >want to tell me why I care, I would appreciate that too.
-
- Before doing any shift operations the compiler performs the integral
- promotions, so the shift in y<<4 is being done on an integer, not an unsigned
- char. The version with the cast should do what you want, because it tells the
- compiler to ignore any bits out beyond the end of an unsigned char when it does
- the shift right. This means that the high bits should get filled with zeros. Of
- course, the final version works because the value of the left shift is
- explicitly stored as an unsigned char.
- -- Pete
-
-